##  Copyright (C) 2009 by Johann Duscher (alias Jonny Dee)
##
##  This file is part of PyoRhythm.
##
##  PyoRhythm is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  PyoRhythm is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with PyoRhythm.  If not, see <http://www.gnu.org/licenses/>.

from __future__ import division
import math

from PyQt4 import QtCore
from PyQt4 import QtGui

from pyorhythm.util import subtractTimes


class Person(QtCore.QObject):
    _cyclePen = dict()
    _showCycle = dict()

    def __init__(self, name, birthTime=None, parent=None):
        QtCore.QObject.__init__(self, parent)

        self.setName(name)
        self.setBirthTime(birthTime)

        self.setShowCycle(BioRhythm.AverageCycle, True)
        self.setShowCycle(BioRhythm.EmotionalCycle, True)
        self.setShowCycle(BioRhythm.IntellectualCycle, True)
        self.setShowCycle(BioRhythm.IntuitiveCycle, True)
        self.setShowCycle(BioRhythm.PhysicalCycle, True)

        self.setCyclePen(BioRhythm.AverageCycle, QtGui.QPen(QtGui.QColor(255, 0, 0), 4, QtCore.Qt.SolidLine))
        self.setCyclePen(BioRhythm.EmotionalCycle, QtGui.QPen(QtGui.QColor(0, 255, 0), 2, QtCore.Qt.SolidLine))
        self.setCyclePen(BioRhythm.IntellectualCycle, QtGui.QPen(QtGui.QColor(0, 0, 255), 2, QtCore.Qt.SolidLine))
        self.setCyclePen(BioRhythm.IntuitiveCycle, QtGui.QPen(QtGui.QColor(255, 255, 0), 2, QtCore.Qt.SolidLine))
        self.setCyclePen(BioRhythm.PhysicalCycle, QtGui.QPen(QtGui.QColor(255, 0, 255), 2, QtCore.Qt.SolidLine))


    def setBirthTime(self, birthTime):
        self._birthTime = birthTime
        self.emit(QtCore.SIGNAL('personChanged'), self)


    def getBirthTime(self):
        return self._birthTime


    def setName(self, name):
        QtCore.QObject.setObjectName(self, name)
        self.emit(QtCore.SIGNAL('personChanged'), self)


    def getName(self):
        return QtCore.QObject.objectName(self)


    def setShowCycle(self, cycle, flag):
        self._showCycle[cycle] = flag
        self.emit(QtCore.SIGNAL('personChanged'), self)


    def isShowCycle(self, cycle):
        return self._showCycle[cycle]


    def setCyclePen(self, cycle, pen):
        self._cyclePen[cycle] = pen
        self.emit(QtCore.SIGNAL('personChanged'), self)


    def getCyclePen(self, cycle):
        return self._cyclePen[cycle]


class BioRhythm:
    AverageCycle = 0
    EmotionalCycle = 28
    IntellectualCycle = 33
    IntuitiveCycle = 38
    PhysicalCycle = 23

    @staticmethod
    def calcBioValue(cycle, person, time):
        if BioRhythm.AverageCycle != cycle:
            theta = 2.0 * math.pi / cycle
            days = subtractTimes(time, person.getBirthTime())
            return math.sin(days*theta)
        else:
            return BioRhythm._calcAverageBioValue(person, time)


    @staticmethod
    def _calcAverageBioValue(person, time):
        return (
            BioRhythm.calcBioValue(BioRhythm.EmotionalCycle, person, time)
            + BioRhythm.calcBioValue(BioRhythm.IntellectualCycle, person, time)
            + BioRhythm.calcBioValue(BioRhythm.IntuitiveCycle, person, time)
            + BioRhythm.calcBioValue(BioRhythm.PhysicalCycle, person, time)
        ) / 4.0
